package com.rybbaby.tss.core.web.service.imp;

import com.rybbaby.tss.core.bean.PageBean;
import com.rybbaby.tss.core.web.dao.imp.GenericDao;
import com.rybbaby.tss.core.web.service.IViewService;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

@Service
public class ViewServiceImp<T> extends GenericDao<T> implements IViewService<T> {

    /**
     * 当前开启的session
     **/
    private Session session;

    /**
     * 重写父类中获取一个新的session的方法
     *
     * @return
     */
    public Session getSession() {
        this.session = this.sessionFactory.openSession();
        return session;
    }

    /**
     * 关闭当前开启的session
     */
    private void closeSession() {
        if (this.session != null) {
            this.session.close();
        }
    }

    /**
     * 根据Id获取一个实体对象
     *
     * @param viewClass
     * @param id        主键id
     */
    @Override
    public T get(Class<T> viewClass, Serializable id) {
        this.getSession();
        T t = session.get(viewClass, id);
        closeSession();
        return t;
    }

    /**
     * 根据属性值该实体的唯一记录，如果有多条记录，将返回第一条记录
     *
     * @param viewClass
     * @param propertyName 属性名
     * @param value        属性值
     * @return
     */
    @Override
    public T findUniqueByProperty(Class<T> viewClass, String propertyName, Object value) {
        T t = super.findUniqueByProperty(viewClass, propertyName, value);
        closeSession();
        return t;
    }

    /**
     * 根据属性值该实体类的记录
     *
     * @param viewClass
     * @param propertyName 属性名
     * @param value        属性值
     * @return
     */
    @Override
    public List<T> findByProperty(Class<T> viewClass, String propertyName, Object value) {
        List<T> list = super.findByProperty(viewClass, propertyName, value);
        closeSession();
        return list;
    }

    /**
     * 加载某一个实体的所有数据
     *
     * @param viewClass
     */
    @Override
    public List<T> loadAll(Class<T> viewClass) {
        List<T> list = super.loadAll(viewClass);
        closeSession();
        return list;
    }

    /**
     * 通过hql 查询语句查找对象，并以实体类型集合返回
     *
     * @param hql hql语句
     * @return
     */
    @Override
    public List<T> findByHql(String hql) {
        List<T> list = super.findByHql(hql);
        closeSession();
        return list;
    }

    /**
     * 根据属性值该实体类的记录
     *
     * @param viewClass    封装查询数据的对象（此参数可以不受Hibernate管制，普通的pojo即可）
     * @param propertyName 属性名
     * @param value        属性值
     * @param isAsc        是否升序排列
     */
    @Override
    public List<T> findByPropertyisOrder(Class<T> viewClass, String propertyName, Object value, boolean isAsc) {
        List<T> list = super.findByPropertyisOrder(viewClass, propertyName, value, isAsc);
        closeSession();
        return list;
    }

    /**
     * 执行hql语句查询查找对象
     *
     * @param hql    hql语句
     * @param params 参数
     */
    @Override
    public List<T> findByHql(String hql, Object[] params) {
        List<T> list = super.findByHql(hql, params);
        closeSession();
        return list;
    }

    /**
     * 通过DetachedCriteria查询指定下标开始查询指定数据量的的数据集
     *
     * @param dc       查询条件对象
     * @param pageNo   当前页
     * @param pageSize 每一页显示的记录数
     */
    @Override
    public PageBean pageList(DetachedCriteria dc, int pageNo, int pageSize) {
        PageBean pageBean = super.pageList(dc, pageNo, pageSize);
        closeSession();
        return pageBean;
    }

    /**
     * 使用指定的检索标准检索数据并分页返回数据
     *
     * @param sql      要执行查询的sql，此sql只需要专注查询，不需要写分页相关的代码
     * @param pageNo   当前页
     * @param pageSize 每一页显示的记录数
     * @return
     */
    @Override
    public PageBean pageList(String sql, int pageNo, int pageSize) {
        PageBean pageBean = super.pageList(sql, pageNo, pageSize);
        closeSession();
        return pageBean;
    }

    /**
     * 通过hql 查询语句查找对象,并以键值对返回
     *
     * @param hql hql语句
     * @return
     */
    @Override
    public Map<Object, Object> getHashMapbyHql(String hql) {
        Map<Object, Object> map = super.getHashMapbyHql(hql);
        closeSession();
        return map;
    }

    /**
     * 通过sql查询语句查找对象
     *
     * @param viewClass 封装查询数据的对象（此参数可以不受Hibernate管制，普通的pojo即可）
     * @param sql       查询类型sql语句，sql语句中的查询库字段别名，必须是cls参数中存在的属性名
     * @param params    SQL语句中的参数，请注意参数与sql语句中参数暂未符?的对应关系
     * @return
     * @throws Exception
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    @Override
    public List<T> findListBySql(Class<T> viewClass, String sql, Object... params) throws Exception {
        return super.findListBySql(sql, viewClass, params);
    }

    /**
     * 将原生sql返回的结果集注入到指定的可不受Hibernate管制实体bean中（待测试）
     *
     * @param viewClass     封装查询数据的对象（此参数可以不受Hibernate管制，普通的pojo即可）
     * @param sql           查询语句
     * @param columnAliases 手动指定需要返回的数据库字段别名，别名必须是cls参数中存在的属性名
     * @param params        SQL语句中的参数，请注意参数与sql语句中参数暂未符?的对应关系
     * @return
     */
    @Override
    public List<T> findListBySql(Class<T> viewClass, String sql, String[] columnAliases, Object... params) throws Exception {
        return super.findListBySql(sql, columnAliases, viewClass, params);
    }
}
